package common.core.domain.http;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.QueryStringDecoder;
import io.netty.handler.codec.http.multipart.DefaultHttpDataFactory;
import io.netty.handler.codec.http.multipart.FileUpload;
import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder;
import io.netty.handler.codec.http.multipart.InterfaceHttpData;
import io.netty.util.CharsetUtil;
import lombok.Data;

import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Data
public class httpApiProtocol {

    private ChannelHandlerContext ctx;
    private InetSocketAddress remoteAddress;
    private Map<String, List<String>> params = new HashMap<>();

    private String apiName;
    private String protocol;
    private String method;
    private HttpMethod httpMethod = HttpMethod.GET;
    private String version;

    private String remoteIP;
    private int remotePort;
    private String localIP;
    private int localPort;


    public httpApiProtocol(ChannelHandlerContext ctx, InetSocketAddress remoteAddress, Object msg){
        this.ctx = ctx;
        this.remoteAddress = remoteAddress;

        String remoteAddrStr = remoteAddress.toString();
        String[] remoteAddr = remoteAddrStr.split(":");

        this.remoteIP = remoteAddr[0].replace("/","");
        this.remotePort = Integer.parseInt(remoteAddr[1]);

        InetSocketAddress localAddress = (InetSocketAddress)ctx.channel().localAddress();
        String localAddrStr = localAddress.toString();
        this.localIP = localAddrStr.split(":")[0].replace("/","");
        this.localPort =Integer.parseInt(localAddrStr.split(":")[1]);

        parseParams(msg);

    }

    private void parseParams(Object msg){

        FullHttpRequest fullHttpRequest = (FullHttpRequest)msg;

        HttpMethod method = fullHttpRequest.method();
        if(method.equals(HttpMethod.GET)){
            QueryStringDecoder decoder = new QueryStringDecoder(fullHttpRequest.uri());
            Map<String, List<String>> params = decoder.parameters();
            this.apiName = params.get("apiName").get(0);
            this.protocol = params.get("protocol").get(0);
            this.method = params.get("method").get(0);
            this.version = params.get("version").get(0);
        }else if(method.equals(HttpMethod.POST)){
            String contentType = fullHttpRequest.headers().get("Content-Type");
            if(contentType.equals("application/json")){
                String jsonStr = fullHttpRequest.content().toString(CharsetUtil.UTF_8);
                Map<String, List<String>> params = JSON.parseObject(jsonStr,Map.class);
                this.apiName = params.get("apiName").get(0);
                this.protocol = params.get("protocol").get(0);
                this.method = params.get("method").get(0);
                this.version = params.get("version").get(0);
            }else if(contentType.equals("application/x-www-form-urlencoded")){
                String content = fullHttpRequest.content().toString(CharsetUtil.UTF_8);
                QueryStringDecoder decoder = new QueryStringDecoder(content,false);
                Map<String, List<String>> params = decoder.parameters();
                this.apiName = params.get("apiName").get(0);
                this.protocol = params.get("protocol").get(0);
                this.method = params.get("method").get(0);
                this.version = params.get("version").get(0);
            }else if(contentType.startsWith("multipart/form-data")){
                HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(new DefaultHttpDataFactory(DefaultHttpDataFactory.MINSIZE), fullHttpRequest, CharsetUtil.UTF_8);
                List<InterfaceHttpData> datas = decoder.getBodyHttpDatas();
                for(InterfaceHttpData data : datas){
                    if(data.getHttpDataType() == InterfaceHttpData.HttpDataType.FileUpload) {
                        FileUpload fileUpload = (FileUpload) data;

                    }
                }
            }
        }
    }
}
